package game.Engine.Entity;

import java.awt.geom.Rectangle2D;

import game.Engine.Entity.Magic.MagicType;
import game.display.Animation;

/**
 * This represents a creature within our game(Alien/Player)
 * @author Justin
 *
 */
public abstract class Creature extends Entity {

   protected static final double BASE_DAMAGE = 25;
   private boolean onGround;
   protected volatile double health;
   protected volatile double maxHealth;
   protected MagicType element;

   protected static long[] magicCooldowns = {500000000L, 1250000000L, 1250000000L, 1250000000L, 4000000000L};
   public Creature(double x, double y, Animation gi) {
      super(x, y, gi);
      maxHealth = 100;
      health = 100;
   }
   
   /**
    * Gets the health of the creature
    * @return Health
    */
   public double getHealth() {
      return health;
   }

   /**
    * Sets the health of the creature back to its original starting health
    */
   public void fullHeal(){
	   setHealth(getMaxHealth());
   }

   /**
    * Gets the max health of the creature
    * @return
    */
   public double getMaxHealth() {
      return maxHealth;
   }
   
   /**
    * Sets the health of the creature
    * @param maxHealth The health you want give to the creature
    */
   public void setMaxHealth(double maxHealth) {
      this.maxHealth = maxHealth;
   }

   /**
    * Is called when the creature is falling
    * Sets onGround to false
    */
   public void fall() {
      setOnGround(false);
   }

   /**
    * Sets the health of the creature
    * @param health The health of the creature
    */
   public void setHealth(double health) {
      this.health = health;
   }

   /**
    * Gets the magic type of the creature
    * @return element The magic type
    */
   public MagicType getElement() {
      return element;
   }
   
   /**
    * Reduces the health when the creature has been hit
    * @param d The amount you reduce the creatures health by
    */
   public void hit(double d) {
      setHealth(getHealth() - d);
      checkDeath();
   }
   
   /**
    * Checks to see if the creature is dead
    * If health is <= 0, then the creature is dead
    */
   public void checkDeath() {
      if(health <= 0) {
         die();
      }
   }
   
   /**
    * Sets the creatures element to a specific type
    * @param element The type of MagicType the creature is going to be
    */
   public void setElement(MagicType element) {
      this.element = element;
   }

   @Override
   public void update(long timeElapsed) {
      super.update(timeElapsed);
      double toX = x + (timeElapsed * dx) / 1000000000;
      double toY = y + (timeElapsed * dy) / 1000000000;
      if (canMove(timeElapsed, toX, toY))
         move(timeElapsed);
      else
         adjustCourseAndMove(timeElapsed);

   }

   /**
    * Checks to see if the creature collides with entity t
    * @param t The entity you are checking to see if the creature collides with
    * @return True if the creature collides with entity t, false otherwise
    */
   public boolean collidesWith(Entity t) {
      Rectangle2D.Double us = getBoundingBox();
      Rectangle2D.Double them = t.getBoundingBox();
      Rectangle2D intersect = us.createIntersection(them);
      if (intersect.getWidth() > 0.000025 && intersect.getHeight() > 0.000025) {
         return true;
      } else {
         return false;
      }
   }

   /**
    * Returns if the creature is on the ground
    * @return True if the creature is on the ground, false otherwise
    */
   public boolean isOnGround() {
      return onGround;
   }

   /**
    * Sets onGround to the passed parameter
    * @param onGround
    */
   public void setOnGround(boolean onGround) {
      this.onGround = onGround;
   }
}